Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

ООП в JavaScript (WaterElemental)
Goto page 1, 2  Next
Author Message
WaterElemental
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Nov 21, 2007 12:08 pm (написано за 1 минуту 8 секунд)
   Post subject: ООП в JavaScript
Reply with quote

Здравствуйте! Я очень хотел бы изучить Object Javascript. Укжите пожалуйста на явные ошибки в логике в следующем коде. Заранее большое спасибо!

        // Карана
    function Chaos(){
        abstract;
    }

        // Элементарная сущность Хаоса
    function Daemon(Lord){
        if(Lord)
            this.parent = Lord;
        // ...
    }

        // Сложная сущность Хаоса.
        // Отличие от элементарной сущности - может находиться в нескольких физически-разделённых объектах текущего состояния
    function God(){
        // ...
                // Описание ипостасей как JS-методов...
    }

        // Текущее состояние. Левый абсолют - Материум.
    function World(){
        this.prototype = new Chaos();
        // ...
    }

        // Не-текущее состояние. Правый абсолют - Имматериум
    function Warp(){
        this.prototype = new Chaos();
        // ...
    }

    // Абстрактный объект, описывающий некоторое промежуточное состояние между Материальной и Нематериальной вселенными. Скользящее состояние
    function subWave {
        this.prototype = new Chaos();
        // ...
    }
    
        // Человек. Разделение по полу весьма условно. Пол указывается в виде числа из интервала {не отрезка!} - (0..1)
    function Person(sex){
        this.prototype = new God();
        this.sex = sex;
        this.Mind = new Object();
        this.Mind.DaemonList = new Array();
        // ...
    }

        // Дух
        function Spirit(){
          this.prototype = new Daemon();
        // ...
        }
Back to top
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Wed Nov 21, 2007 4:15 pm (спустя 4 часа 6 минут)
   Post subject:
Reply with quote


М

Уважаемый, зачем Вы создали тему в Мусоропроводе :)?

Перенесено из форума: Мусоропровод.
Перенесено в форум: Разное :: JavaScript.
Back to top
View user's profile Send private message Send e-mail
WaterElemental
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Nov 21, 2007 4:58 pm (спустя 43 минуты; написано за 3 минуты 27 секунд)
   Post subject:
Reply with quote

Юрий Насретдинов - я посчитал что многими людьми оно будет расценено как глупая шутка. Часто люди пишут чтобы накрутить количество сообщений, показать что они существуют, показать что мыслительный процесс у них есть. Чем больше комплексов - тем больше всё это необходимо, и сражаться с ними мне бы не очень хотелось.
Создал в мусоропроводе, в надежде что кто-нибудь через поиск (поиском как правило пользуются люди с мозгом) найдёт тему, и чего-нибудь да пояснит.
Back to top
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Wed Nov 21, 2007 5:18 pm (спустя 20 минут; написано за 2 минуты 4 секунды)
   Post subject:
Reply with quote

Code (JavaScript): скопировать код в буфер обмена
function Warp(){
        this.prototype = new Chaos();
        // ...
    }
Так - не сработает :( Нужно писать
Code (JavaScript): скопировать код в буфер обмена
function Warp(){
        // ...
    }
 Warp.prototype = Chaos;
Back to top
View user's profile Send private message Send e-mail
Guest






Карма: 388
   поощрить/наказать


PostPosted: Wed Nov 21, 2007 6:23 pm (спустя 1 час 5 минут; написано за 3 минуты 24 секунды)
   Post subject:
Reply with quote

Ksnk если написать
Code (JavaScript): скопировать код в буфер обмена
Warp.prototype.Constructor = new Chaos();
то Warp.prototype будет содержать копию функции Chaos и изменения последней не будут иметь никаких последствий для Warp()?
Back to top
kernel32
Участник форума



Joined: 18 Mar 2006
Posts: 256
Карма: 24
   поощрить/наказать

Location: Москва

PostPosted: Wed Nov 21, 2007 6:48 pm (спустя 24 минуты; написано за 1 минуту 52 секунды)
   Post subject:
Reply with quote

Может, так?
Code (JavaScript): скопировать код в буфер обмена
function myFunction() {
        alert('test! this is myFunction');
}
Warp.prototype.someMethod = myFunction;
var myVar; myVar = new Warp();
myVar.someMethod();
Back to top
View user's profile Send private message
Валенок
Участник форума



Joined: 06 Apr 2006
Posts: 520
Карма: -3
   поощрить/наказать


PostPosted: Wed Nov 21, 2007 6:55 pm (спустя 7 минут; написано за 4 минуты 2 секунды)
   Post subject:
Reply with quote

Anonymous wrote:
Ksnk если написать
Code (JavaScript): скопировать код в буфер обмена
Warp.prototype.Constructor = new Chaos();
то Warp.prototype будет содержать копию функции Chaos и изменения последней не будут иметь никаких последствий для Warp()?
во-первых, да, а во-вторых, не функции, а класса
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Wed Nov 21, 2007 7:28 pm (спустя 33 минуты; написано за 13 секунд)
   Post subject:
Reply with quote

Code (JavaScript): скопировать код в буфер обмена
function obj(name){
  this.name=name;
  this.method=function(){alert('obj.method')};
}
/////////////////////
function obj1(name){
  this.prototype=new obj(name); //
}
/////////////////////
function obj2(name){
  arguments.callee.prototype.apply(this,arguments); //
}
obj2.prototype=obj;
/////////////////////
var o1=new obj1('Me');
var o2=new obj2('Me');
alert([o1.method,o1.name,o2.method,o2.name]);
Второй способ работает, в отличии от первого.
Back to top
View user's profile Send private message Send e-mail
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Wed Nov 21, 2007 7:44 pm (спустя 16 минут; написано за 3 минуты 8 секунд)
   Post subject:
Reply with quote

Гость wrote:
...не будут иметь никаких последствий для Warp()...
Что такое последствия?
Code (JavaScript): скопировать код в буфер обмена
function obj(name){
  this.name=name;
  this.method=function(){alert('obj.method')};
}

/////////////////////
function obj1(name){
 //
}
obj1.prototype=new obj('Hello!');
/////////////////////
function obj2(name){
  arguments.callee.prototype.apply(this,arguments); //
}
obj2.prototype=obj;

obj.method2=function(){alert('obj.method2');}
/////////////////////
var o1=new obj1('Again');
var o2=new obj2('Me');
alert(['\no1',o1.method,o1.name,o1.method2,'\no2',o2.method,o2.name,o2.method2]);
В первом случае я затруднился вызвать наследуемый конструктор.
Во втором случае все прекрасно отражается, что, впрочем, и не удивительно...
Back to top
View user's profile Send private message Send e-mail
WaterElemental
Заглянувший



Joined: 21 Nov 2007
Posts: 16
Карма: 0
   поощрить/наказать

Location: Земля

PostPosted: Wed Nov 21, 2007 8:43 pm (спустя 59 минут; написано за 8 минут 25 секунд)
   Post subject:
Reply with quote

Благодарю всех за потраченное время.
Ksnk wrote:
Что такое последствия?
Влияние изменения одного класса (Chaos) на работу конструктора другого класса (Warp).

Необходимо создать массив Heavens состоящий из семи элементов, каждый из которых является экземпляром класса subWave.
Code (JavaScript): скопировать код в буфер обмена
function subWave {
         ...
        this.param1 = ...;
        this.method1 = {...};
        ...
    }

 subWave.prototype = new Chaos();

 var Heavens = new Array(7);
 var i;
 for(i=0;i<7;i++){
        Heavens[i] = new subWave();
 }
Корректно ли это?
Heavens[X].method1() и Heavens[X].param1 - существуют для всех X из [0..6]? каждый элемент будет являться экземпляром subWave (изменение которого будет влиять на все элементы массива), а subWave будет потомком Chaos()?

Заранее большое спасибо!
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Wed Nov 21, 2007 8:49 pm (спустя 5 минут; написано за 1 минуту 35 секунд)
   Post subject:
Reply with quote

imho, корректно . однако я бы написал вот так
Code (JavaScript): скопировать код в буфер обмена
subWave.prototype = Chaos; // Без всякого new... И так много хаоса ;)

 var Heavens = [];
 for(var i=0;i<7;i++){
        Heavens.push( new subWave());
 }
Back to top
View user's profile Send private message Send e-mail
WaterElemental
Заглянувший



Joined: 21 Nov 2007
Posts: 16
Карма: 0
   поощрить/наказать

Location: Земля

PostPosted: Wed Nov 21, 2007 9:09 pm (спустя 19 минут; написано за 4 минуты 43 секунды)
   Post subject:
Reply with quote

Ksnk
Но ведь Вы написали
Code (JavaScript): скопировать код в буфер обмена
obj1.prototype=new obj('Hello!');
Я запутался немного. В приведённом участке Вашего кода, предок obj1 и obj2 разве является копией(!) obj?

Из класса нельзя обращаться к предку (this.prototype), а из объекта - без проблем. Это утверждение соответствует действительности?
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Wed Nov 21, 2007 9:30 pm (спустя 20 минут; написано за 7 минут 14 секунд)
   Post subject:
Reply with quote

Это было написано для сравнения! объекты obj1 и obj2 отличаются полем name и method2. Поле method1 у них одинаковое. Изменения в прототипе после создания объекта влияют на obj2 и не влияют на obj1. obj2 мне нравится больше :)

классов в JavaScript нет. Уточните, что вы имеете ввиду под этим словом.
Back to top
View user's profile Send private message Send e-mail
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Wed Nov 21, 2007 9:44 pm (спустя 14 минут; написано за 2 минуты 22 секунды)
   Post subject:
Reply with quote

Можно почитать наблы 38 (dklab.ru/chicken/nablas/38.html),39 (dklab.ru/chicken/nablas/39.html) и 40 (dklab.ru/chicken/nablas/38.html). В конце 40-й приведена функция, которая позволяет "наследовать" объекты почти так, как в обычном OOП-языке.
Back to top
View user's profile Send private message Send e-mail
WaterElemental
Заглянувший



Joined: 21 Nov 2007
Posts: 16
Карма: 0
   поощрить/наказать

Location: Земля

PostPosted: Wed Nov 21, 2007 10:04 pm (спустя 20 минут; написано за 1 минуту 45 секунд)
   Post subject:
Reply with quote

Ksnk wrote:
классов в JavaScript нет. Уточните, что вы имеете ввиду под этим словом.
Вопрос можно переформулировать так: в примере для сравнения Вы использовали new для указания прототипа, однако потом привели вот такой пример
Code (JavaScript): скопировать код в буфер обмена
subWave.prototype = Chaos;
где записывается ссылка.
Разве эти два способа эквивалентны?

Last edited by WaterElemental on Thu Nov 22, 2007 9:03 am; edited 1 time in total
Back to top
View user's profile Send private message
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Wed Nov 21, 2007 11:59 pm (спустя 1 час 54 минуты; написано за 14 минут 1 секунду)
   Post subject:
Reply with quote

WaterElemental
Боюсь нарваться на несогласие со стороны общественности, высказав мысли явно противоположные мыслям Ksnk относительно почти естественного наследования как в обычных ООП-языках.

Попробую аргументировать.
Используя сторонний проект (сторонюю библиотеку), вы явно завязаны на его API, следовательно вы обязаны использовать все предоставляемые этим проектом интерфейсы.
Если возможностей данного проекта недостаточно, то для появления необходимой возможности вы вольны поступать в соответствии одним из следующих путей
1. наследовать новый класс средствами стороннего проекта
2. наследовать "в ручную" - используя только средства языка
3. реализовать требуемый функционал посредством стандартных функций (без использования ООП)

Если же вам требуется организовать библиотеку, обладающую определенной функциональностью, то необходимо в самом начале спроектировать программный интерфейс вашей библиотеки.
Поверьте, это очень важный пункт. Разработка нескольких моих замыслов приостанавливалась из-за необходимости полной или частичной реструктуризации кода.

Чтение ранее названных набл необходимо. Но если вы считаете, что они сложны, оставьте. вернетесь к ним позже.
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Thu Nov 22, 2007 12:31 am (спустя 31 минуту; написано за 47 секунд)
   Post subject:
Reply with quote

Ну ладно. Я, видимо в достаточной степени запутался :(
Code (JavaScript): скопировать код в буфер обмена
function obj(name){
  this.name=name;
  this.test=0;
  this.method=function(){
      this.test++;
      alert('obj.method')
  };
}
function obj2(name){
  arguments.callee.prototype.apply(this,arguments); //
}
obj2.prototype=obj;

obj.method2=function(){alert('obj.method2');}
var o2=new obj2('Me');
В рекламируемом мной способе (без new) нельзя сделать "реальное" наследование. Это просто "объединение" всех методов собственно объекта и его родителя. Причем сам факт объединения вызывается этой странной строчкой в функции obj2. Поле prototype в этом случае используется просто для хранения указателя на конструктор предка.
Таким образом, если объект и родитель имеют поле с одним и тем-же именем - одно из них потеряется.
Code (JavaScript): скопировать код в буфер обмена
function obj1(name){
   this.prototype=arguments.callee.prototype;
   this.test='Hello'; //
   this.method=function(){
       this.prototype.method(); //
   }       
}
obj1.prototype=new obj('x');

var Obj1=new obj1();
Obj1.method()
при таком методе наследования потерять родительский метод не удается, все поля родительского объекта надежно сохранены ;) однако минусы его - нельзя вызвать конструктор предка внутри собственного конструктора, и требуется вставлять магическую строчку "this.prototype=arguments.callee.prototype;", чтобы добраться до собственного прототипа.

...

Возвращаясь к нашим небесам, можно написать
Code (JavaScript): скопировать код в буфер обмена
function chaos(){...}
var Chaos=new chaos(); // Это будет единственный экземпляр.

function subWave {
        this.prototype=arguments.callee.prototype; // немного магии
         ...
        this.param1 = ...;
        this.method1 = {...};
        ...
    }
subWave.prototype = Chaos; // Хаос един и всеобъемлющь

 var Heavens = [];
 for(var i=0;i<7;i++){
        Heavens.push( new subWave());
 }
Надеюсь, ясности получилось больше, чем туману ;)

Last edited by Ksnk on Thu Nov 22, 2007 2:42 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
WaterElemental
Заглянувший



Joined: 21 Nov 2007
Posts: 16
Карма: 0
   поощрить/наказать

Location: Земля

PostPosted: Thu Nov 22, 2007 9:10 am (спустя 8 часов 39 минут; написано за 1 минуту 54 секунды)
   Post subject:
Reply with quote

Rumata wrote:
Чтение ранее названных набл необходимо. Но если вы считаете, что они сложны, оставьте. вернетесь к ним позже.
Нет, совсем не сложны. Я около полугода назад их перечитал несколько раз (JavaScript-овые наблы) - разбирался с .prototype и .prototype.constructor
Они до сих пор у меня на рабочем месте в распечатанном виде. Правда, уже все засаленные... но вполне читаемые ещё.

Ksnk
Самое оно! Благодарствую.
Back to top
View user's profile Send private message
Андрей Сумин
Участник форума



Joined: 23 Nov 2005
Posts: 60
Карма: 5
   поощрить/наказать

Location: Москва

PostPosted: Thu Nov 22, 2007 2:04 pm (спустя 4 часа 54 минуты; написано за 2 минуты 13 секунд)
   Post subject:
Reply with quote

Сначала прочесть, потом задавать вопросы

blogs.msdn.com/jscript/archive/2007/09/24/classes-in-jscript-part-i.aspx
blogs.msdn.com/jscript/archive/2007/09/30/classes-in-jscript-part-ii-instance-properties-methods-class-properties-methods.aspx
blogs.msdn.com/jscript/archive/2007/10/31/classes-in-jscript-part-iii-class-hierarchy-and-data-encapsulation.aspx

Я полность согласен с Rumata. В JS отличное ООП, но извините prototype based а не class based. И не стоит тратить кучу сил впустую, стараясь сделать "типа нормальное наследование", а просто изучить язык.
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Thu Nov 22, 2007 3:58 pm (спустя 1 час 53 минуты; написано за 6 минут 35 секунд)
   Post subject:
Reply with quote

Андрей Сумин перечитайте, пожалуйста топик. Где вы видите выраженное WaterElemental желание "сделать нормальное наследование"? Было выражено желание изучать JavaScript, для чего было преложено описать на нем некую объектно-зависимую схему. Если у вас возникло ощущуение, что преложенный мной каркас, на котором можно построить решение имеет какие-то серьезные изьяны, я, и, вероятно, WaterElemental будем счастливы услышать какие-то убедительные соображения по этому поводу. Пока, все услышанные возражения можно сформулировать без потери смысла - "что-то вы ерундой занимаетесь" и "умные люди делают по другому".
Back to top
View user's profile Send private message Send e-mail
WaterElemental
Заглянувший



Joined: 21 Nov 2007
Posts: 16
Карма: 0
   поощрить/наказать

Location: Земля

PostPosted: Thu Nov 22, 2007 4:14 pm (спустя 16 минут; написано за 2 минуты 25 секунд)
   Post subject:
Reply with quote

Ksnk
Да, именно по этой причине я и поместил тему в "Мусоропровод", в третьем сообщении (от начала топика) я описал именно такую ситуацию. Ссылки, разумеется, очень полезны. Но отрицательная эмоциональная окраска, которую несёт сообщение, не идёт на пользу развитию :'(
Back to top
View user's profile Send private message
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Nov 22, 2007 5:31 pm (спустя 1 час 16 минут; написано за 8 минут 45 секунд)
   Post subject:
Reply with quote

WaterElemental
Сказать по правде, мне лично идеология ООП не очень-то близка, особенно множественные наследования, переписывание методов предка, и т.д. :).

Я лично максимум, что использую в своём «арсенале» JavaScript -- это одна из реализаций «классов», которую предложил Дима Котеров:
Code (JavaScript): скопировать код в буфер обмена
var someClass = new (function()
{
        var T = this; /* алиас для this класса, чтобы не было путаницы с this вложенных методов */

        var hiddenprop = 'траляля'; /* эквивалент protected свойств и методов */
        T.publicprop = 'какое-то публичное свойство';
       
        var hiddenfunc = function(someparam) /* protected функция */
        {
                hiddenprop = ' => ' + someparam; /* делает какую-то глубокомысленную операцию со внутренним свойством :) */
        }
       
        T.publicfunc = function ()
        {
                return hiddenprop;
        }

        T.add = function(what)
        {
                hiddenfunc(what||'(null)');
        }
})();

/* вот как с ними работать */

someClass.add("hello");
someClass.add();
someClass.add("world");

alert(someClass.publicfunc());
Я полагаю, меня участники не поддержат, но такая простенькая организация позволяет сосредоточиться на работе, но не на играх с ООП, и я считаю такую организацию удобной. И именно по такому принципу сделан мой файловый менеджер, ибо без классов или их аналогов очень легко запутаться даже в 50 функциях :).

Last edited by Юрий Насретдинов on Thu Nov 22, 2007 6:25 pm; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Thu Nov 22, 2007 6:11 pm (спустя 40 минут; написано за 7 минут 5 секунд)
   Post subject:
Reply with quote

Юрий Насретдинов большой минус предложенного варианта - его сложно от чего-то унаследовать. Его имеет смысл рассматривать как пример реализации public/private методов. Опять-же, imho, само наличие таких методов подразумевает разработку большого проекта в большом коллективе, только там оно хоть сколько-то оправдано, ибо для маленького проекта достаточно дисциплины и/или соглашений о наименовании методов. К примеру, пусть все приватные методы будут начинаться с подчеркивания и неча их вызывать не по делу ;)
Опять-же, придираясь по мелочи к тексту:
Юрий Насретдинов wrote:
var T = this; ... чтобы не было путаницы с this вложенных методов
Т скорее для того, чтобы hiddenfunc могла оперировать родным объектом. Так как если писать hiddenfunc.call(this,...) - получится несколько больше букв.
Back to top
View user's profile Send private message Send e-mail
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Thu Nov 22, 2007 6:19 pm (спустя 7 минут; написано за 2 минуты 15 секунд)
   Post subject:
Reply with quote

Юрий Насретдинов wrote:
Я полагаю, меня участники не поддержат...
Почему же не поддержат? :)
Я тоже далек от "множественного наследования и переписывания методов предка". Незнаю, куда с ними "пойти-податься". Может быть когда-нибудь, а пока по простому - конструктор, прототип, экземплярчики...
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Nov 22, 2007 6:30 pm (спустя 10 минут; написано за 4 минуты 10 секунд)
   Post subject:
Reply with quote

Ksnk wrote:
Т скорее для того, чтобы hiddenfunc могла оперировать родным объектом. Так как если писать hiddenfunc.call(this,...) - получится несколько больше букв.
Хм... Вроде как, внутри метода this таки указывает на объект класса :). Ну да ладно... В общем, это удобно.
Ksnk wrote:
большой минус предложенного варианта - его сложно от чего-то унаследовать.
Да, с этим проблемы :). Но, сказать по правде, не хочется выносить добавление методов и свойств из конструктора, ибо мне кажется это большим злом и нарушением целостности класса, да ещё и с невозможностью организации приватных свойств и методов. ИМХО лучше попросту сделать как-то так:
Code (JavaScript): скопировать код в буфер обмена
var someClassName = function(parentClass)
{
        if(parentClass && parentClass.prototype) for(var k in parentClass.prototype)
        {
                this[k] = parentClass.prototype[k];
        }
        ...
};

var someClass = new someClassName(otherClass);
Но... Чёрт его знает, как это будет работать :). Оно будет работать лишь с классами, которые были определены как раз с помощью
Code (JavaScript): скопировать код в буфер обмена
var otherClass = function(){}

otherClass.prototype.somemethod = function(){...};
...
То есть, другого подхода, который мне не очень нравится.

AKS
Спасибо :).
Back to top
View user's profile Send private message Send e-mail
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Thu Nov 22, 2007 6:37 pm (спустя 6 минут)
   Post subject:
Reply with quote

AKS wrote:
... Незнаю, куда с ними "пойти-податься"...
А вот сюда ;-) В первом сообщении этого топика была обрисована "теософская картина мира", которую предлагалось смоделировать на JavaScript. Eсли я правильно понял, без возможности "переписывания методов предка", как и без наследования от единственного объекта и возможности работы непосредственно с родителем в конструкции Heavens<->Chaos более менее адекватную картину отобразить не удастся. Надо-же хоть куда-то запихать хоть немного магии и волшебства :)
Back to top
View user's profile Send private message Send e-mail
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Thu Nov 22, 2007 6:49 pm (спустя 12 минут; написано за 1 минуту 6 секунд)
   Post subject:
Reply with quote

Юрий Насретдинов wrote:
Хм... Вроде как, внутри метода this таки указывает на объект класса :).
Неправда ваша :)
Code (JavaScript): скопировать код в буфер обмена
function obj(){
  var func=function(){
    alert(this);
  }
  this.method=function(){func();};
}
var Obj=new obj();
Obj.method();
такой пример в FireFox возвращает [object Window], что не очень похоже на сам объект
Back to top
View user's profile Send private message Send e-mail
An6rey
Участник форума



Joined: 30 Aug 2007
Posts: 69
Карма: 3
   поощрить/наказать


PostPosted: Thu Nov 22, 2007 8:04 pm (спустя 1 час 14 минут; написано за 3 минуты)
   Post subject:
Reply with quote

Ksnk wrote:
Юрий Насретдинов wrote:
Хм... Вроде как, внутри метода this таки указывает на объект класса :).
Неправда ваша :)
Code (JavaScript): скопировать код в буфер обмена
function obj(){
  var func=function(){
    alert(this);
  }
  this.method=function(){func();};
}
var Obj=new obj();
Obj.method();
такой пример в FireFox возвращает [object Window], что не очень похоже на сам объект
Ваше this не втутри метода - внутри функции. Сравните:
Code (JavaScript): скопировать код в буфер обмена
function obj(){
  var func=function(my){
    alert(my);
  }
  this.method=function(){func(this);};
}
var Obj=new obj();
Obj.method();
Back to top
View user's profile Send private message
Андрей Сумин
Участник форума



Joined: 23 Nov 2005
Posts: 60
Карма: 5
   поощрить/наказать

Location: Москва

PostPosted: Thu Nov 22, 2007 9:01 pm (спустя 56 минут; написано за 8 минут 5 секунд)
   Post subject:
Reply with quote

И всетаки баба яга против. Я высказывался не о ком-то лично а о набле как таковой.
Прочитать ее смысл есть, спорить не буду, но если также прочесть весь топик в форуме, в котором ее обсуждают, то можно понять что так делать нет смысла (не буду утверждать точно, но помоему и сам Дмитрий в этом признался).
Для подтвержедения предлагаю используя метод наблы сделать наследдование через 3-4 колена.

Я собственно сам через это проходил пытался наследовать как в набле написано, как это сделано в других источниках, а потом взял да и прочел внимательно спецификацию.
Все стало просто и понятно.
Поэтому высказваю свое мнение: все эти псевдонаследования несостоятельны и менее эффективны чем родное наследования в JS.
Но выходить с этим лозунгом и собирать демонстрации не буду сами решайте что лучше.
Тема топика - желание изучить наследование я привел отличные по моему мнению ссылки.
Back to top
View user's profile Send private message
An6rey
Участник форума



Joined: 30 Aug 2007
Posts: 69
Карма: 3
   поощрить/наказать


PostPosted: Thu Nov 22, 2007 9:42 pm (спустя 40 минут; написано за 21 минуту 43 секунды)
   Post subject:
Reply with quote

Андрей Сумин wrote:
Поэтому высказваю свое мнение: все эти псевдонаследования несостоятельны и менее эффективны чем родное наследования в JS.
Но выходить с этим лозунгом и собирать демонстрации не буду сами решайте что лучше.
Тема топика - желание изучить наследование я привел отличные по моему мнению ссылки.
При организации наследования (родного-или неродного) - проблема не в том каким способом это делать - если речь не о начинающем программисте.
Проблема в том как загрузить код связанных классов до моменнта его использования.

И тут "самопальное" наследование может совместить само наследование и загрузку кода всех необходимых классов методами Ajax.

Посмотрите библиотеки dojo, jsolait.

Наследование при помощи методов копирования свойств так же просто реализовать как и "родное". Но речь, еще повторю, в удобстве использования.
Я вызываю "самопальную" функцию myNamespace.create("myNamespace.Dog","Rex") - и внутри "самопальной" функции
1) загружается код myNamespace/Dog.js
2) загружается код родтельских классов (Animals...)
3) создается новый объект new myNamespace.Dog("Rex")
4) возвращается ссылка на этот объект.
Back to top
View user's profile Send private message
Андрей Сумин
Участник форума



Joined: 23 Nov 2005
Posts: 60
Карма: 5
   поощрить/наказать

Location: Москва

PostPosted: Thu Nov 22, 2007 9:54 pm (спустя 12 минут; написано за 3 минуты 12 секунд)
   Post subject:
Reply with quote

О по этой теме я целые доклады читал на РИТ2007 (rit2007.ru/), ClientSide2007 (www.client2007.ru/), SECON2007 (secon.ru/wiki/Wiki.jsp) и на WSG митинге (webdev.lovata.com/2007/11/19/tretya-vstrecha-wsg-russia/).
Заходите на jsx.ru почитайте, может что пригодится.

Как это все делается у Dojo и еще мгого у каого знаю, лично общался с разработчиками Dojo.
Везде свои плюсы и минусы, но мне кажется загрузка по требованию никак не связана с наследованием.
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Thu Nov 22, 2007 9:57 pm (спустя 3 минуты; написано за 2 секунды)
   Post subject:
Reply with quote

Андрей СуминПозвольте кое-в чем с Вами не согласиться ;)
Андрей Сумин wrote:
...я привел отличные по моему мнению ссылки...
В ссылках разжевывается довольно подробно "традиционно-принятый" для JS метод наследования, которые предполагает описание функций объекта через Obj.prototype.method=function(){...}, что выглядит отвратительно (неэстетично) не только в моих глазах, но и в глазах Юрий Насретдинов'а. В последней главе в предпоследнем примере про "function PositionedRectangle" допущена грубая ошибка. Нельзя было так просто вызвать функцию Rectangle в конструкторе, нужно было сделать Rectangle.call(this,height,width) по понятным, я надеюсь, соображениям.
Итог - ссылки, возможно, полезны, но, imho, слишком поверхностны. И для человека, успевшего за полгода "замусолить" пример из 40-й наблы могут оказаться уже не интересными ;-)

Хотя да, на длинных цепочках наследования я свой креатифф еще не проверял :( Надо будет переписать Ваш пример из обсуждения наблы вдруг чего накопается...

An6rey, я привел пример, imho,демонстрирующий ошибочность мнения Юрий Насретдинов'а. Какое отношение к этому имеет Ваш пример я понять не смог, извините.
Back to top
View user's profile Send private message Send e-mail
Андрей Сумин
Участник форума



Joined: 23 Nov 2005
Posts: 60
Карма: 5
   поощрить/наказать

Location: Москва

PostPosted: Thu Nov 22, 2007 10:07 pm (спустя 9 минут; написано за 48 секунд)
   Post subject:
Reply with quote

Ну да ладно. Останемся при своих мнениях если они помогают каждому писать хороший код!
Back to top
View user's profile Send private message
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Nov 22, 2007 11:20 pm (спустя 1 час 12 минут; написано за 53 секунды)
   Post subject:
Reply with quote

Андрей Сумин wrote:
Я собственно сам через это проходил пытался наследовать как в набле написано, как это сделано в других источниках, а потом взял да и прочел внимательно спецификацию.
Все стало просто и понятно.
Вы бы не могли поделиться своим способом организовать наследование в JavaScript и объяснить, хотя бы мне, зачем это нужно и где это используется?

P.S. Если этот вопрос вызовет у Вас раздражение, можете не пытаться ничего ответить.
Back to top
View user's profile Send private message Send e-mail
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Thu Nov 22, 2007 11:27 pm (спустя 6 минут)
   Post subject:
Reply with quote

Андрей Сумин
Мне не совсем понятно к чему Вы клоните.

Андрей Сумин
Ksnk
Юрий Насретдинов
Мне все же кажется, что автор темы просто пытается понять как работает js - язык, ориентированный на объекты, и каковы его отличия от классического ООП-языка.
При этом обуждение уходит в другое русло - теоретические игры с объектно-ориентированными прототипами в множественно-наследованном пространстве, ограниченном вложенностью вызова this. Простите за резкость (:

По-моему достаточно ответить на вопрос
WaterElemental wrote:
Укжите пожалуйста на явные ошибки в логике в следующем коде
Back to top
View user's profile Send private message
Андрей Сумин
Участник форума



Joined: 23 Nov 2005
Posts: 60
Карма: 5
   поощрить/наказать

Location: Москва

PostPosted: Thu Nov 22, 2007 11:43 pm (спустя 16 минут; написано за 2 минуты 22 секунды)
   Post subject:
Reply with quote

Юрий Насретдинов
Как я уже сказал наследование я использую родное, которое есть в языке - prototype based без каких-либо оберток.
Динамическиа загрузка у меня своя и она описана на сайте, но с наследованием никак не связанно.

Rumata
А вот я не понял фразы "Мне не совсем понятно к чему Вы клоните"
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Fri Nov 23, 2007 1:39 am (спустя 1 час 55 минут; написано за 24 минуты 14 секунд)
   Post subject:
Reply with quote

Rumata Ну вот! А я только собрался предъявить народу новенький креатифф ;-) впрочем, если Вам кажется, что "игры" зашли слишком далеко и автору топика уже не очень интересны - можно выделить обсуждение в отдельную ветку.

Раз уж все здесь присутствующие так тесно знакомы с 40-й наблой - вот вам повод для "нового тура игры" :)
Code (JavaScript): скопировать код в буфер обмена
//
function inherited(method){
        var m=this[method];
        if(!m) return;
        var el=this;
        while(el && !el.hasOwnProperty(method))        el=el.prototype ;
        if(el){
                delete(el[method]);
                var res=this[method] && this[method]();
                el[method]=m;
                return res;
        }
        return ;
}
function newClass(parent, prop) {
  // Dynamically create class constructor.
    var clazz = function(){
        if (prop) {
            var cname = "constructor";
            for (var k in prop) {
                if (k != cname) this[k] = prop[k];
            }
                        if(prop.toString)this.toString = prop.toString;
        }
        this.prototype=parent;
        if (prop[cname] && prop[cname] != Object){
            prop[cname].apply(this, arguments);
        }
    };

    if(!parent)parent={inherited:inherited}; //
    if(typeof(parent)=='function') parent=new parent();
    clazz.prototype = parent;// gain object instead function!!!!
   
    return clazz;
}
Основные, ключевые отличия от варианта Дмитрия Котерова - цепочка наследования идет не по функциям, а по объектам, для чего приходится автоматически генерировать объект из функции с помощью оператора new. При этом, если объект расчитывает в конструкторе на какие-то параметры - придется обломаться :( Новые методы из объекта-шаблона копируются не в clazz.prototype, а в собственно объект в теле функции clazz. Вот, собственно и все. Да! Добавлена фенечка с toString'ом

Примерчик для проверки классовой сути тоже практически полностью утянут из сообщения Андрей Сумин'а из ветки обсуждения этой самой наблы. Изменениям подвергся механизм вывода отладочной информации - trace'ы проставлены вместо document.write и убраны ненужные сейчас .constructor'ы. Также, в теле конструктора отсутствует возможность вызова конструктора наследуемого класса.
Code (JavaScript): скопировать код в буфер обмена
var trace_str='';       
function trace(s){
        if (trace_str.length>100) new Error('Переполнение трассы');
        trace_str+='<br>'+s;
}       
   
// Базовый "класс".
var  CarSpirit=new (newClass(null, {
  fuel:100}))();
         
var Car = newClass(CarSpirit, {
  constructor: function() {
        trace("Вызван конструктор Car().");
  },
  park:function(){
        trace("Вызван Car.park()");
  },
  drive: function() {
        trace("Вызван Car.drive()");
  }
});
// Производный "класс".
Zaporojets = newClass(Car, {
  constructor: function() {
        trace("Вызван конструктор Zaporojets().");
//        this.prototype.constructor.call(this);
  },
  crack: function() {
        trace("Вызван Zaporojets.crack()");
  } ,
  drive: function() {
        trace("Вызван Zaporojets.drive()");
        return this.inherited("drive");
  }
});


Niva = newClass(Zaporojets, {
  toString:function(){return "Niva!";},       
  constructor: function() {
        trace("Вызван конструктор Niva().");
//        this.prototype.constructor.call(this);
  },
  drive: function() {
        trace("Вызван Niva.drive()");
        return this.inherited("drive");
  }
});
try {
var vehicle = new Niva();
vehicle.fuel--;
trace(vehicle.fuel);
trace(CarSpirit.fuel);
vehicle.crack(); // вызывается функция родителя
vehicle.park(); // вызывается функция родителя
vehicle.drive(); // вызывается функция родителя
if(vehicle instanceof Car) trace('instance of Car');
trace(vehicle);

// проверяем, что наследником у нас - один объект.
trace(CarSpirit.hello+' | '+vehicle.hello);
CarSpirit.hello=new String('Hello!');
trace(CarSpirit.hello+' | '+vehicle.hello);
vehicle.hello+=' world';
trace(CarSpirit.hello+' | '+vehicle.hello);
} catch(e){
  alert(["Описание ошибки: ", e]);
}
       
document.getElementById('trace').innerHTML=trace_str;
Вот!

P.S. Добавлен корректный вызов метода предшественника.

Last edited by Ksnk on Sat Nov 24, 2007 6:10 pm; edited 5 times in total
Back to top
View user's profile Send private message Send e-mail
WaterElemental
Заглянувший



Joined: 21 Nov 2007
Posts: 16
Карма: 0
   поощрить/наказать

Location: Земля

PostPosted: Fri Nov 23, 2007 9:05 am (спустя 7 часов 26 минут; написано за 2 минуты 31 секунду)
   Post subject:
Reply with quote

Ksnk wrote:
В методе drive объекта Zaporojets применен финт ушами - prototype указан два раза!!!
Разве прототип прототипа вызывается не через конструктор?

Вообщем-то есть ещё один глупый вопрос. Самый верхний класс (Chaos) является абстрактным на первых итерациях разработки. Возможно ли в будущем добавлять в него функционал из объектов-потомков {в объект-предок}? (то есть декларация самого класса останется как и есть сейчас)
Back to top
View user's profile Send private message
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Fri Nov 23, 2007 9:47 am (спустя 41 минуту; написано за 9 минут 57 секунд)
   Post subject:
Reply with quote

А нету никакого конструктора. В этом варианте цепочка наследования - цепочка объектов. А в объекте, в отличии от функции, нет особенного смысла в методе prototype. Вот я его и перегружаю. Здесь prototype - то, что у Дмитрия было prototype.constructor. imho такой вариант несколько более "интуитивно-понятен" ;)

Наткнулся на неприятную фичу такого способа наследования. Она демонстрируется строчками
Code (JavaScript): скопировать код в буфер обмена
trace(CarSpirit.hello+' | '+vehicle.hello);
CarSpirit.hello='Hello!';
trace(CarSpirit.hello+' | '+vehicle.hello);
vehicle.hello+=' world';
trace(CarSpirit.hello+' | '+vehicle.hello);
примера.
результат работы
Code (any language): скопировать код в буфер обмена
undefined | undefined
Hello! | Hello!
Hello! | Hello! world
Хотя значение свойства hello храниться в объекте CarSpirit, при работе с ним оно копируется в основной объект.
В принципе, постфактум, становится очевидно, что в момент, когда выполняется операция += срабатывает this.hello=this.hello+' world', и создается новое поле у "верхнего" объекта, но иногда хочется верить в Деда мороза :(
решением будет - хранить такие "общие поля" в виде объектов. Так как все в JS за некоторым исключением чисел и строк - ссылки, у нас вполне сработает такое:
Code (JavaScript): скопировать код в буфер обмена
trace(CarSpirit.hello+' | '+vehicle.hello);
CarSpirit.hello=new String('Hello!'); //
trace(CarSpirit.hello+' | '+vehicle.hello);
vehicle.hello+=' world';
trace(CarSpirit.hello+' | '+vehicle.hello);
Back to top
View user's profile Send private message Send e-mail
Ksnk
Участник форума



Joined: 24 Jun 2005
Posts: 459
Карма: 49
   поощрить/наказать

Location: СПб

PostPosted: Fri Nov 23, 2007 10:18 am (спустя 31 минуту; написано за 2 минуты 46 секунд)
   Post subject:
Reply with quote

WaterElemental wrote:
Вообщем-то есть ещё один глупый вопрос. Самый верхний класс (Chaos) является абстрактным на первых итерациях разработки. Возможно ли в будущем добавлять в него функционал из объектов-потомков {в объект-предок}? (то есть декларация самого класса останется как и есть сейчас)
А почему, собственно, этот вопрос кажется Вам глупым? Я, можно сказать, именно из-за этого вопроса и поднимаю тут шум ;-) Предыдущее мое сообщение является ответом?
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Goto page 1, 2  Next
Page 1 of 2    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML